package com.hbnu.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hbnu.system.config.BaseException;
import com.hbnu.system.constant.AuthorTypeConstants;
import com.hbnu.system.mapper.PaperMapper;
import com.hbnu.system.mapper.PaperauthorMapper;
import com.hbnu.system.model.entity.Paper;
import com.hbnu.system.model.entity.Paperauthor;
import com.hbnu.system.model.entity.User;
import com.hbnu.system.service.IPaperQualificationService;
import com.hbnu.system.service.IPaperService;
import com.hbnu.system.service.IPaperauthorService;
import com.hbnu.system.service.IUserService;
import com.hbnu.system.utils.CheckRoleUtil;
import com.hbnu.system.utils.IdGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 论文作者服务实现类
 */
@Service
public class PaperauthorServiceImpl extends ServiceImpl<PaperauthorMapper, Paperauthor> implements IPaperauthorService {

    @Autowired
    private IPaperService iPaperService;

    @Autowired
    private IUserService iUserService;

    @Autowired
    private CheckRoleUtil checkRoleUtil;
    
    @Autowired
    private IPaperQualificationService iPaperQualificationService;

    @Autowired
    private PaperMapper paperMapper;

    private static final List<String> AUTHOR_TYPE_ORDER = Arrays.asList(
            "第一作者", "共同第一作者", "通讯作者", "第二作者", "第三作者", "其他排名"
    );

    // 用于保留两位小数的格式化器
    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.00");

    /**
     * 添加论文作者
     * @param paperauthor 论文作者信息
     * @return 添加操作是否成功
     */
    @Override
    public boolean addPaperAuthor(Paperauthor paperauthor) {
        // 不使用前端传过来的id，生成新id
        paperauthor.setPaperAuthorID(null);
        Paper paper = paperMapper.selectById(paperauthor.getPaperID());
        checkRoleUtil.checkPermissionAchievement(paper.getStatus());

        //如果是校外作者或者学生，为其生成工号
        if (AuthorTypeConstants.OUT_SCHOOL_AUTHOR.equals(paperauthor.getPeopleType())
                ||paperauthor.getPeopleType().equals(AuthorTypeConstants.STUDENT)) {
            paperauthor.setUserAccount(IdGenerator.generateId());
        }

        // 检查工号是否为空
        if (paperauthor.getUserAccount().isEmpty()) {
            throw new BaseException("请输入工号");
        }

        // 检查是否重复添加
        Paperauthor existingAuthor = getOne(
                Wrappers.lambdaQuery(Paperauthor.class)
                        .eq(Paperauthor::getPaperID, paperauthor.getPaperID())
                        .eq(Paperauthor::getUserAccount, paperauthor.getUserAccount())
        );
        if (Objects.nonNull(existingAuthor)) {
            throw new BaseException("不可重复添加");
        }

        // 检查考核系数(支持整数和小数)
        double newAssessment;
        try {
            String assessment = paperauthor.getAssessment();
            // 如果考核系数为null或空，默认为0
            if (assessment == null || assessment.trim().isEmpty()) {
                newAssessment = 0.0;
            } else {
                newAssessment = Double.parseDouble(assessment);
            }
        } catch (NumberFormatException e) {
            throw new BaseException("考核系数格式不正确");
        }
        if (newAssessment < 0 || newAssessment > 100) {
            throw new BaseException("考核系数应在 0 到 100 之间");
        }

        String Pscore = "0.00";

//        Paper_Qualification paperQualification = iPaperQualificationService.getById(paperauthor.getPaperID());

        Paper paper1=iPaperService.getPaper(paperauthor.getPaperID());
        if(paper1 != null){
            int finalValue = (int) paper1.getScore();
            // 计算并保留两位小数
            double pscore = finalValue * newAssessment / 100.0;
            Pscore = DECIMAL_FORMAT.format(pscore);
        }

        // 计算已填写考核系数的作者总和
        List<Paperauthor> authors = list(
                Wrappers.lambdaQuery(Paperauthor.class)
                        .eq(Paperauthor::getPaperID, paperauthor.getPaperID())
        );
        double totalAssessment = authors.stream()
                .filter(author -> !author.getAssessment().equals(""))
                .mapToDouble(author -> Double.parseDouble(author.getAssessment()))
                .sum();
        if (totalAssessment + newAssessment > 100) {
            throw new BaseException("已填写作者考核系数总和大于100!");
        }

        paperauthor.setPscore(Pscore);

        boolean result = save(paperauthor);
        if (result) {
            updateAllAuthor(paper, paperauthor);
        }
        return result;
    }

    /**
     * 删除论文作者
     * @param id 作者ID
     * @return 删除操作是否成功
     */
    @Override
    public boolean deletePaperAuthor(String id) {
        Paperauthor paperauthor = super.getOne(Wrappers.lambdaQuery(Paperauthor.class)
                .eq(Paperauthor::getPaperAuthorID, id));
        if (Objects.isNull(paperauthor)) {
            throw new BaseException("不存在关联作者");
        }

        Paper paper = iPaperService.getOne(Wrappers.lambdaQuery(Paper.class)
                .eq(Paper::getPaperID, paperauthor.getPaperID()));
        checkRoleUtil.checkPermissionAchievement(paper.getStatus());

        boolean result = baseMapper.deleteById(paperauthor) == 1;
        if (result) {
            updateAllAuthor(paper, paperauthor);
        }
        return result;
    }

    /**
     * 修改论文作者
     * @param paperauthor 论文作者信息
     * @return 修改操作是否成功
     */
    @Override
    public boolean updatePaperAuthor(Paperauthor paperauthor) {
        Paper paper = paperMapper.selectById(paperauthor.getPaperID());
        checkRoleUtil.checkPermissionAchievement(paper.getStatus());

        double newAssessment;
        try {
            String assessment = paperauthor.getAssessment();
            // 如果考核系数为null或空，默认为0
            if (assessment == null || assessment.trim().isEmpty()) {
                newAssessment = 0.0;
            } else {
                newAssessment = Double.parseDouble(assessment);
            }
        } catch (NumberFormatException e) {
            throw new BaseException("考核系数格式不正确");
        }
        if (newAssessment > 100 || newAssessment < 0) {
            throw new BaseException("输入数据应在0-100范围内");
        }
        String Pscore = "0.00";

        Paper paper1=iPaperService.getPaper(paperauthor.getPaperID());
        if(paper1 != null){
            int finalValue = (int) paper1.getScore();
            // 计算并保留两位小数
            double pscore = finalValue * newAssessment / 100.0;
            Pscore = DECIMAL_FORMAT.format(pscore);
        }

        // 查询该论文的所有作者
        List<Paperauthor> paperauthorList = query().eq("PaperID", paperauthor.getPaperID()).list();
        double sum = 0;
        // 只计算已填写考核系数的作者（排除当前修改的作者）
        for (Paperauthor author : paperauthorList) {
            if (!author.getPaperAuthorID().equals(paperauthor.getPaperAuthorID())) {
                if(!StrUtil.isBlank(author.getAssessment())){
                    sum += Double.parseDouble(author.getAssessment());
                }
            }
        }
        // 检查已填写作者考核系数总和是否超过100
        if (sum + newAssessment > 100) {
            throw new BaseException("已填写作者考核系数总和大于100!");
        }

        paperauthor.setPscore(Pscore);

        boolean result = baseMapper.updateById(paperauthor) == 1;
        if (result) {
            updateAllAuthor(paper, paperauthor);
        }
        return result;
    }

    /**
     * 获取论文作者
     * @param id 论文ID
     * @return 论文作者列表
     */
    @Override
    public List<Paperauthor> listAuthor(String id) {
        List<Paperauthor> list = baseMapper.selectList(Wrappers.lambdaQuery(Paperauthor.class)
                .eq(Paperauthor::getPaperID, id));
        list.sort(Comparator.comparingInt(p -> AUTHOR_TYPE_ORDER.indexOf(p.getAuthortype())));
        return list;
    }



    /**
     * 维护AllAuthor字段
     * @param paper 论文对象
     * @param paperauthor 当前操作的作者
     */
    private void updateAllAuthor(Paper paper, Paperauthor paperauthor) {
        // 1. 先删除原来的AllAuthor字段
        paper.setAllAuthor(null);
        iPaperService.updateById(paper);

        // 2. 查询该论文的所有作者
        List<Paperauthor> allAuthorList = listAuthor(paper.getPaperID());
        // 3. 按照作者类型排序
        allAuthorList.sort(Comparator.comparingInt(p -> AUTHOR_TYPE_ORDER.indexOf(p.getAuthortype())));
        // 4. 根据工号集合查询用户的主键id
        List<String> userAccountList = allAuthorList.stream()
                .map(Paperauthor::getUserAccount)
                .collect(Collectors.toList());
        List<User> userList = new ArrayList<>();
        if (!userAccountList.isEmpty()) {
            userList = iUserService.list(Wrappers.lambdaQuery(User.class)
                    .in(User::getAccount, userAccountList));
        } else {
            // 如果没有作者，确保userList为空列表而不是null
            userList = new ArrayList<>();
        }
        List<String> uidList = userList.stream()
                .map(User::getUid)
                .collect(Collectors.toList());
        // 筛选出用户的名字集合，格式：姓名【作者属性】(如果作者属性为空则只显示姓名)
        List<String> nameWithTypeList = allAuthorList.stream()
                .map(author -> {
                    String name = author.getName();
                    String authorType = author.getAuthortype();
                    // 如果作者类型为空或null，只返回姓名
                    if (authorType == null || authorType.trim().isEmpty()) {
                        return name;
                    }
                    // 否则返回 姓名【作者属性】
                    return name + "【" + authorType + "】";
                })
                .collect(Collectors.toList());
        // 5. 将主键id拼接成字符串
        String allAuthor = String.join(",", uidList);
        // 更新AllAuthorName字段(格式：姓名【作者属性】、姓名【作者属性】)
        paper.setAllAuthorName(String.join("、", nameWithTypeList));
        // 6. 更新AllAuthor字段
        paper.setAllAuthor(allAuthor);
        iPaperService.updateById(paper);
    }
}